#include <iostream>
#include <vector>

#define ROW 20
#define COL 60

class matrix
{
private:
    std::vector<int> body;
    int row = 0;
    int column = 0;

public:
    int &operator()(int i, int j)
    {
        return body[j + column * i];
    }

    matrix(int r, int c)
    {
        body.resize(r * c);
        row = r;
        column = c;
    }

    ~matrix()
    {
        body.clear();
    }

    matrix &operator=(matrix &B)
    {
        this->body.clear();
        for (int i = 0; i < B.row * B.column; i++)
        {
            this->body.push_back(B.body[i]);
        }
        return *this;
    }

    void print()
    {
        for (int i = 0; i < this->row; i++)
        {
            for (int j = 0; j < this->column; j++)
            {
                if ((*this)(i, j) == 0)
                    std::cout << '-';
                else
                    std::cout << '*';
            }
            printf("\n");
        }
        std::cout << '\n';
    }

    void init()
    {
        int i = 1, j = 1;
        while (i != -1 && i <= ROW && j != -1 && j <= COL)
        {
            std::cin >> i >> j;
            (*this)(i - 1, j - 1) = 1;
        }
    }

    int getRound(int r, int c)
    {
        int sum = 0;
        for (int i = r - 1; i <= r + 1; i++)
        {
            for (int j = c - 1; j <= c + 1; j++)
            {
                if (i >= 0 && j >= 0)
                {
                    sum += (*this)(i, j);
                }
            }
        }
        sum -= (*this)(r, c); // Remove itself
        return sum;
    }

    void update()
    {
        matrix REC(ROW, COL);
        for (int i = 0; i < this->row; i++)
        {
            for (int j = 0; j < this->column; j++)
            {
                if ((*this)(i, j) == 1)
                {
                    int n = this->getRound(i, j);
                    if (n <= 1 || n >= 4)
                        REC(i, j) = 0;
                    if (n == 3 || n == 2)
                        REC(i, j) = 1;
                }
                else
                {
                    int n = this->getRound(i, j);
                    if (n == 3)
                        REC(i, j) = 1;
                }
            }
        }
        (*this) = REC;
    }
};

void welcome()
{
    std::cout << "Welcome to Conway's game of Life.\n\
This game uses a grid of size 20 by 60 in which\n\
each cell can either be occupied by an organism or not\n\
The occupied cells change from generation to generation\n\
according to the number of neighboring cells which are alive.\n\
List the coordinatesfor living cells.\n\
Terminate the list with the special pair (-1, -1)\n";
}

int main()
{
    welcome();
    matrix A(ROW, COL);
    A.init();
    A.print();

    char key = 'Y';
    while (1)
    {
        std::cout << "Continue? (Y/n): ";
        std::cin >> key;
        std::cout << std::endl;
        if (key == 'Y' || key == 'y')
        {
            A.update();
            A.print();
            continue;
        }
        break;
    }
    return 0;
}
